<?php

/**
 * @Author: Wang chunsheng  email:2192138785@qq.com
 * @Date:   2022-08-18 14:31:59
 * @Last Modified by:   Wang chunsheng  email:2192138785@qq.com
 * @Last Modified time: 2023-04-16 11:10:41
 */

namespace Common;


use Common\Component\Singleton;
use Common\Helpers\DebugHelper;
use Hyperf\Context\ApplicationContext;
use Hyperf\Contract\ConfigInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Swoole\Table as SwooleTable;


class BaseTable
{
    use Singleton;

    public const TYPE_INT = 1;

    public const TYPE_STRING = 3;

    public const TYPE_FLOAT = 2;


    /**
     * Registered swoole tables.
     *
     * @var array
     */
    protected array $tables = [];


    /**
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function __construct(string $key = 'swoole_table')
    {
        /**
         * @var ConfigInterface $config
         */
        $config = ApplicationContext::getContainer()->get(ConfigInterface::class);
        // 通过 get(string $key, $default): mixed 方法获取 $key 所对应的配置，$key 值可以通过 . 连接符定位到下级数组，$default 则是当对应的值不存在时返回的默认值
        $tables =  $config->get($key);
        foreach ($tables as $tableName => $tableConfig) {
            if (!isset($tableConfig['size'], $tableConfig['columns'])) {
                continue;
            }
            $tableSize = $tableConfig['size'];
            $tableColumns =  $tableConfig['columns'];

            $table = new SwooleTable($tableSize);

            foreach ($tableColumns as $name => $column) {
                $table->column($name, $column['type'], $column['size']);
            }

            if (!($this->hasTable($tableName))){
                DebugHelper::consoleWrite('创建内存表',$tableName);
                $table->create();
            }
            $tables[$tableName] = $table;
        }
        $this->tables = $tables;
    }



    public function hasTable(string $name): bool
    {
        return isset($this->tables[$name]);
    }

    public function getTable(string $name): ?SwooleTable
    {
        return $this->tables[$name] ?? null;
    }

    /**
     * Add a swoole table to existing tables.
     *
     * @param string $name
     * @param SwooleTable $table
     * @return BaseTable
     */
    public function add(string $name, SwooleTable $table): static
    {
        $this->tables[$name] = $table;

        return $this;
    }

    /**
     * Get a swoole table by its name from existing tables.
     *
     * @param string $name
     * @return SwooleTable|null $table
     */
    public function get(string $name): ?SwooleTable
    {
        return $this->tables[$name] ?? null;
    }

    /**
     * Get all existing swoole tables.
     *
     * @return array
     */
    public function getAll(): array
    {
        return $this->tables;
    }

    /**
     * Dynamically access table.
     *
     * @return SwooleTable
     */
    public function __get(string $key)
    {
        return $this->get($key);
    }
}
